home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
comm
/
ns_16550.zip
/
FACT.C
< prev
next >
Wrap
Text File
|
1991-07-20
|
14KB
|
435 lines
/* FFFFFFF A CCCCCC TTTTTTTTTTT CCCCCC
* F A A C T C
* FFFFF A A C T C
* F A AAA A C T C
* F A A C T .. C
* F A A CCCCCC T .. CCCCCC
*
* FACT.C -- FIFO Asynchronous Communication Test Program for
* NS16550 and NS16552 UARTs
*
* Greg DeJager Ver 1.0 1/31/89
*
* Adapted from LBT.C -- LoopBack Test Rev 1.1
* Developed By: Brian A. Berg
* Berg Software Design
* October 1988
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include "stdhdr.h"
#include "serio.h"
/* define some macros for use herein */
/* program test name for user prompt and help screen */
#define TESTNAME "NS16550/NS16552 FIFO Asynchronous Communications Test (FACT)"
/* clear the RBR, LSR and IIR registers (used at start and before exit) */
#define CLEAR_REGS() ((void)rdRBR(), (void)rdRBR(), \
(void)rdLSR(), (void)rdIIR(), (void)wrMCR(0), \
(void)wrFCR(CLR_FIFO))
/* GET ctrl-break/ctrl-c checking flag status via "INT 21H" */
#define GETBRK() (regs.h.ah = 0x33, regs.h.al = 0, \
intdos(®s, ®s), regs.h.dl)
/* SET ctrl-break/ctrl-c checking flag to argument via "INT 21H" */
#define SETBRK(brk) (regs.h.ah = 0x33, regs.h.al = 1, \
regs.h.dl = (brk), intdos(®s, ®s))
/* COMx-dependent parameters */
UINT comvnum[COM_CNT] = {0x0C, 0x0B, 0x0B}; /* int. vector nos. for COMx */
UINT uartbadd[COM_CNT] = {0x3F8, 0x2F8, 0x3220}; /* UART base adds. for COMx */
UINT picmsk[COM_CNT] = {0xEF, 0xF7, 0xF7}; /* PIC masks for COMx: IRQ4,3 */
/* declare parameters and default values; override via invocation line args. */
/* argument 1: COM number */
int com = COM_DEF;
UINT ivnum; /* int. vector number (set as comvnum[com-1]) */
UINT ubase; /* UART base address (set as uartbadd[com-1]) */
/* argument 2: baud rate divisor */
int baudiv = BAUDIV_DEF;
UCHAR bytwr = 0; /* write byte counter (goes from 0 to 255) */
UCHAR bytrd = 0; /* read byte counter (goes from 0 to 255) */
UCHAR iir, lsr; /* storage for IIR and LSR */
UCHAR bytin; /* input byte storage */
UINT errflag = FALSE; /* error indication and ID */
/* storage for original environment parameters */
void far *savect; /* interrupt vector */
UCHAR savbrk; /* ctrl-break flag */
UINT savmsk; /* PIC mask */
UCHAR savier; /* IER register */
UCHAR savlcr; /* LCR register */
UCHAR savmcr; /* MCR register */
UCHAR savdll; /* DLL register */
UCHAR savdlm; /* DLM register */
CNVTR cnvtr; /* handy union for data type conversions */
union REGS regs; /* 16- and 8-bit registers for intdos() */
int finit = FALSE; /* boolean for program termination */
/* globals which control the tick mark on the screen */
int tick = FALSE; /* boolean for display of "tick" on CRT */
int tick_ff = 0; /* tick flip-flop (either 0 or 1) */
int bytick = 0; /* helps determine when to set tick boolean */
UCHAR *tickstr[] = {"\b*", "\b$"}; /* "tick" mark strings */
/* Routines contained herein: */
void main(int, char **); /* main program */
void interrupt far serint(void); /* serial interrupt handler */
void procarg(int, char **); /* process invocation arguments */
void savepar(void); /* save our environment parameters */
void rstrpar(void); /* restore our environment parameters */
void dspstr(UCHAR *); /* display a string to console */
void usage(void); /* display usage info and exit */
/*
* main(): main program
*/
void main(argc, argv)
int argc;
char **argv;
{
/* process invocation args., and set up int vector no. and UART base add */
procarg(argc, argv); /* get com# and baudrate from argument string */
CLEAR_REGS(); /* clear RBR, LSR, IIR, MCR, and FIFOs */
savepar(); /* save our environment parameters */
/* set baud rate */
wrLCR(0x80); /* set DLAB */
cnvtr.intval[0] = baudiv;
outp(DLL, cnvtr.chrval[0]);
outp(DLM, cnvtr.chrval[1]);
wrLCR(0x0B); /* 8 data, 1 stop, odd parity */
printf("\n\n %s\n\n",TESTNAME); /*startup message*/
/* wait loop to insure other machine has cleared its registers */
printf("\nHit a key when other program has been started.\n\n");
while( !(kbhit() && getch()) );
/* set up registers for our environment */
wrFCR(CLR_FIFO); /* clear transmitter and receiver FIFOs */
wrFCR(FIFO_EN); /* enable FIFOs, set Rx trigger at 14 bytes */
if ( (rdIIR() & 0xc0) != 0xc0) /* ensure FIFOs present */
{
printf("\nFatal Error. FIFOs not present\n");
errflag = ENDPROG;
}
wrMCR(OUT2); /* enable PIC interrupt (OUT2) */
wrIER(IER_VAL1); /* Enable LSI and RDAI */
wrMCR(0x0a); /* Assert RTS (and OUT2) */
printf("Waiting for first 'Request To Send' from other machine...\n\n");
while (!(rdMSR() & CTS)); /* wait for other machine to assert RTS */
printf("\n\nHit non-control key to stop: ");
/* Enable Tx interupts; loop until int. handler finished or any key struck */
wrIER(IER_VAL2);
while (!errflag)
{
if (kbhit() && getch())
errflag = ENDPROG;
if (tick) /* display tick mark */
{
/* display the tick mark */
printf("%s",tickstr[tick_ff]);
tick_ff = 1 - tick_ff; /* update tick flip-flop */
tick = FALSE;
}
}
wrIER(0); /* disable UART interrupts */
while ( !(rdLSR() & TEMT) ); /* wait for Tx FIFO to clear */
CLEAR_REGS(); /* clear RBR, LSR, MCR and IIR registers before we exit */
/* Output error message represented by 'errflag' variable */
switch (errflag)
{
case ENDPROG: /* keyboard hit or fatal error */
break;
case FALSEINT: /* IIR shows no interrupt active */
printf("\nFalse interrupt. No UART interrupt active.\n");
break;
case STATUSERR: /* Line Status interrupt generated */
printf("\nLine Status interrupt. LSR = %x\n",lsr);
printf("Byte causing LSI = %x\n",bytin);
break;
case MISMATCH: /* Data received did not match data expected */
printf("\nData mismatch\n");
printf("Byte expected = %x\n",--bytrd);
printf("Byte received = %x\n",bytin);
break;
case RX_ERROR: /* RDAI generated but DR was not set */
printf("\nError: RDAI but no DR indication\n");
break;
case TX_ERROR: /* THREI generated but THRE was not set */
printf("\nError: THREI but no THRE indication\n");
break;
case IIR_ERROR: /* Invalid IIR */
printf("\nIIR invalid\n");
break;
case TIMEOUT: /* Character Timeout Interrupt */
printf("\nCharacter Timeout.\n");
break;
case TIMEOUT_ERR: /* False Character Timeout Interrupt */
printf("\nError: False Character Timeout Interrupt.\n");
break;
default:
break;
} /* end of switch */
rstrpar(); /* restore our environment parameters */
printf("\n\n\nEnd of program; Environment parameters restored.\n");
} /* end of main() */
/*
* serint(): serial port interrupt handler
*/
void interrupt far serint()
{
int bytecnt=0;
/* if errflag has been set, ignore the interrupt */
if (errflag)
{
wrIER(0);
outp(PICTRL, EOI); /* send EOI to 8259A PIC */
return;
}
/* here's the code to handle each of the various interrupt types */
switch (iir = rdIIR())
{
case F_NOIP: /* NO Interrupt Pending */
errflag = FALSEINT;
break;
case F_RLST: /* Receiver Line STatus interrupt */
lsr = rdLSR();
bytin